// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.util.list;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import zombie.core.Rand;
import zombie.core.math.PZMath;
import zombie.util.ICloner;
import zombie.util.Pool;
import zombie.util.StringUtils;

public class PZArrayUtil {
    public static final int[] emptyIntArray = new int[0];
    public static final float[] emptyFloatArray = new float[0];

    public static <E> E pickRandom(E[] object) {
        if (object.length == 0) {
            return null;
        } else {
            int _int = Rand.Next(object.length);
            return (E)object[_int];
        }
    }

    public static <E> E pickRandom(List<E> list) {
        if (list.isEmpty()) {
            return null;
        } else {
            int _int = Rand.Next(list.size());
            return (E)list.get(_int);
        }
    }

    public static <E> E pickRandom(Collection<E> collection) {
        if (collection.isEmpty()) {
            return null;
        } else {
            int _int = Rand.Next(collection.size());
            return getElementAt(collection, _int);
        }
    }

    public static <E> E pickRandom(Iterable<E> iterable) {
        int int0 = getSize(iterable);
        if (int0 == 0) {
            return null;
        } else {
            int int1 = Rand.Next(int0);
            return getElementAt(iterable, int1);
        }
    }

    public static <E> int getSize(Iterable<E> collection) {
        int _int = 0;
        Iterator iterator = collection.iterator();

        while (iterator.hasNext()) {
            _int++;
            iterator.next();
        }

        return _int;
    }

    public static <E> E getElementAt(Iterable<E> iterable, int int1) throws ArrayIndexOutOfBoundsException {
        Object object = null;
        Iterator iterator = iterable.iterator();

        for (int int0 = 0; int0 <= int1; int0++) {
            if (!iterator.hasNext()) {
                throw new ArrayIndexOutOfBoundsException(int0);
            }

            if (int0 == int1) {
                object = iterator.next();
            }
        }

        return (E)object;
    }

    public static <E> void copy(ArrayList<E> target, ArrayList<E> source) {
        copy(target, source, object -> object);
    }

    public static <E> void copy(ArrayList<E> target, ArrayList<E> source, ICloner<E> elementCloner) {
        if (target != source) {
            target.clear();
            target.ensureCapacity(source.size());

            for (int _int = 0; _int < source.size(); _int++) {
                Object object = source.get(_int);
                target.add(elementCloner.clone(object));
            }
        }
    }

    public static <E> int indexOf(E[] object0, Predicate<E> predicate) {
        try {
            for (int _int = 0; _int < object0.length; _int++) {
                Object object1 = object0[_int];
                if (predicate.test(object1)) {
                    return _int;
                }
            }

            return -1;
        } finally {
            Pool.tryRelease(predicate);
        }
    }

    public static <E> int indexOf(List<E> collection, Predicate<E> comparer) {
        int int0;
        try {
            int int1 = -1;

            for (int int2 = 0; int2 < collection.size(); int2++) {
                Object object = collection.get(int2);
                if (comparer.test(object)) {
                    int1 = int2;
                    break;
                }
            }

            int0 = int1;
        } finally {
            Pool.tryRelease(comparer);
        }

        return int0;
    }

    public static <E> boolean contains(E[] object, Predicate<E> predicate) {
        return indexOf(object, predicate) > -1;
    }

    public static <E> boolean contains(List<E> collection, Predicate<E> comparer) {
        return indexOf(collection, comparer) > -1;
    }

    public static <E> boolean contains(Collection<E> it, Predicate<E> comparer) {
        if (it instanceof List) {
            return contains((List<E>)it, comparer);
        } else {
            boolean boolean0;
            try {
                boolean boolean1 = false;

                for (Object object : it) {
                    if (comparer.test(object)) {
                        boolean1 = true;
                        break;
                    }
                }

                boolean0 = boolean1;
            } finally {
                Pool.tryRelease(comparer);
            }

            return boolean0;
        }
    }

    public static <E> boolean contains(Iterable<E> it, Predicate<E> comparer) {
        if (it instanceof List) {
            return indexOf((List<E>)it, comparer) > -1;
        } else {
            boolean boolean0;
            try {
                boolean boolean1 = false;

                for (Object object : it) {
                    if (comparer.test(object)) {
                        boolean1 = true;
                        break;
                    }
                }

                boolean0 = boolean1;
            } finally {
                Pool.tryRelease(comparer);
            }

            return boolean0;
        }
    }

    public static <E> E find(List<E> list, Predicate<E> predicate) {
        int _int = indexOf(list, predicate);
        return (E)(_int > -1 ? list.get(_int) : null);
    }

    public static <E> E find(Iterable<E> iterable, Predicate<E> predicate) {
        if (iterable instanceof List) {
            return find((List<E>)iterable, predicate);
        } else {
            Object object0;
            try {
                Iterator iterator = iterable.iterator();

                Object object1;
                do {
                    if (!iterator.hasNext()) {
                        return null;
                    }

                    object1 = iterator.next();
                } while (!predicate.test(object1));

                object0 = object1;
            } finally {
                Pool.tryRelease(predicate);
            }

            return (E)object0;
        }
    }

    public static <E, S> List<E> listConvert(List<S> source, Function<S, E> converter) {
        return (List<E>)(source.isEmpty() ? PZArrayList.<E>emptyList() : new PZConvertList(source, converter));
    }

    public static <E, S> Iterable<E> itConvert(Iterable<S> source, Function<S, E> converter) {
        return new PZConvertIterable(source, converter);
    }

    public static <E, S> List<E> listConvert(List<S> source, List<E> dest, Function<S, E> converter) {
        dest.clear();

        for (int _int = 0; _int < source.size(); _int++) {
            dest.add(converter.apply(source.get(_int)));
        }

        return dest;
    }

    public static <E, S, T1> List<E> listConvert(List<S> list1, List<E> list0, T1 object, PZArrayUtil.IListConverter1Param<S, E, T1> iListConverter1Param) {
        list0.clear();

        for (int _int = 0; _int < list1.size(); _int++) {
            list0.add(iListConverter1Param.convert(list1.get(_int), object));
        }

        return list0;
    }

    private static <E> List<E> asList(E[] object) {
        return Arrays.asList(object);
    }

    private static List<Float> asList(float[] _float) {
        return new PrimitiveFloatList(_float);
    }

    private static <E> Iterable<E> asSafeIterable(E[] object) {
        return (Iterable<E>)(object != null ? asList((E[])object) : PZEmptyIterable.getInstance());
    }

    private static Iterable<Float> asSafeIterable(float[] _float) {
        return (Iterable<Float>)(_float != null ? asList(_float) : PZEmptyIterable.getInstance());
    }

    public static String arrayToString(float[] _float) {
        return arrayToString(asSafeIterable(_float));
    }

    public static String arrayToString(float[] _float, String string0, String string1, String string2) {
        return arrayToString(asSafeIterable(_float), string0, string1, string2);
    }

    public static <E> String arrayToString(E[] object) {
        return arrayToString(asSafeIterable((E[])object));
    }

    public static <E> String arrayToString(E[] object, String string0, String string1, String string2) {
        return arrayToString(asSafeIterable((E[])object), string0, string1, string2);
    }

    public static <E> String arrayToString(Iterable<E> list, Function<E, String> toString) {
        return arrayToString(list, toString, "{", "}", System.lineSeparator());
    }

    public static <E> String arrayToString(Iterable<E> list) {
        return arrayToString(list, String::valueOf, "{", "}", System.lineSeparator());
    }

    public static <E> String arrayToString(Iterable<E> list, String prefix, String suffix, String delimiter) {
        return arrayToString(list, String::valueOf, prefix, suffix, delimiter);
    }

    public static <E> String arrayToString(Iterable<E> list, Function<E, String> toString, String prefix, String suffix, String delimiter) {
        StringBuilder stringBuilder = new StringBuilder(prefix);
        if (list != null) {
            boolean _boolean = true;

            for (Object object : list) {
                if (!_boolean) {
                    stringBuilder.append(delimiter);
                }

                String string = (String)toString.apply(object);
                stringBuilder.append(string);
                _boolean = false;
            }
        }

        stringBuilder.append(suffix);
        Pool.tryRelease(toString);
        return stringBuilder.toString();
    }

    public static <E> E[] newInstance(Class<?> _class, int _int) {
        return (E[])((Object[])Array.newInstance(_class, _int));
    }

    public static <E> E[] newInstance(Class<?> _class, int int0, Supplier<E> supplier) {
        Object[] object = newInstance(_class, int0);
        int int1 = 0;

        for (int int2 = object.length; int1 < int2; int1++) {
            object[int1] = supplier.get();
        }

        return (E[])object;
    }

    public static <E> E[] newInstance(Class<?> _class, E[] object, int _int) {
        return (E[])newInstance(_class, object, _int, false, () -> null);
    }

    public static <E> E[] newInstance(Class<?> _class, E[] object, int _int, boolean _boolean) {
        return (E[])newInstance(_class, object, _int, _boolean, () -> null);
    }

    public static <E> E[] newInstance(Class<?> _class, E[] object, int _int, Supplier<E> supplier) {
        return (E[])newInstance(_class, object, _int, false, supplier);
    }

    public static <E> E[] newInstance(Class<?> _class, E[] object0, int int0, boolean _boolean, Supplier<E> supplier) {
        if (object0 == null) {
            return (E[])newInstance(_class, int0, supplier);
        } else {
            int int1 = object0.length;
            if (int1 == int0) {
                return (E[])object0;
            } else if (_boolean && int1 > int0) {
                return (E[])object0;
            } else {
                Object[] object1 = newInstance(_class, int0);
                arrayCopy(object1, object0, 0, PZMath.min(int0, int1));
                if (int0 > int1) {
                    for (int int2 = int1; int2 < int0; int2++) {
                        object1[int2] = supplier.get();
                    }
                }

                if (int0 < int1) {
                    for (int int3 = int0; int3 < int1; int3++) {
                        object0[int3] = Pool.tryRelease(object0[int3]);
                    }
                }

                return (E[])object1;
            }
        }
    }

    public static float[] add(float[] float1, float float2) {
        float[] float0 = new float[float1.length + 1];
        arrayCopy(float0, float1, 0, float1.length);
        float0[float1.length] = float2;
        return float0;
    }

    public static <E> E[] add(E[] object1, E object2) {
        Object[] object0 = newInstance(object1.getClass().getComponentType(), object1.length + 1);
        arrayCopy(object0, object1, 0, object1.length);
        object0[object1.length] = object2;
        return (E[])object0;
    }

    public static <E> E[] concat(E[] object0, E[] object1) {
        boolean boolean0 = object0 == null || object0.length == 0;
        boolean boolean1 = object1 == null || object1.length == 0;
        if (boolean0 && boolean1) {
            return null;
        } else if (boolean0) {
            return (E[])clone(object1);
        } else if (boolean1) {
            return (E[])object0;
        } else {
            Object[] object2 = newInstance(object0.getClass().getComponentType(), object0.length + object1.length);
            arrayCopy(object2, object0, 0, object0.length);
            arrayCopy(object2, object1, object0.length, object2.length);
            return (E[])object2;
        }
    }

    public static <E, S extends E> E[] arrayCopy(E[] object1, S[] object0, int int1, int int2) {
        for (int int0 = int1; int0 < int2; int0++) {
            object1[int0] = object0[int0];
        }

        return (E[])object1;
    }

    public static float[] arrayCopy(float[] float1, float[] float0, int int1, int int2) {
        for (int int0 = int1; int0 < int2; int0++) {
            float1[int0] = float0[int0];
        }

        return float1;
    }

    public static int[] arrayCopy(int[] int4, int[] int3, int int1, int int2) {
        for (int int0 = int1; int0 < int2; int0++) {
            int4[int0] = int3[int0];
        }

        return int4;
    }

    public static <L extends List<E>, E> L arrayCopy(L list0, List<? extends E> list1) {
        list0.clear();
        list0.addAll(list1);
        return (L)list0;
    }

    public static <E> E[] arrayCopy(E[] object, List<? extends E> list) {
        for (int _int = 0; _int < list.size(); _int++) {
            object[_int] = list.get(_int);
        }

        return (E[])object;
    }

    public static <E, S extends E> E[] arrayCopy(E[] object1, S[] object0) {
        System.arraycopy(object0, 0, object1, 0, object0.length);
        return (E[])object1;
    }

    public static <L extends List<E>, E, S> L arrayConvert(L list0, List<S> list1, Function<S, E> function) {
        list0.clear();
        int int0 = 0;

        for (int int1 = list1.size(); int0 < int1; int0++) {
            Object object = list1.get(int0);
            list0.add(function.apply(object));
        }

        return (L)list0;
    }

    public static float[] clone(float[] float0) {
        if (isNullOrEmpty(float0)) {
            return float0;
        } else {
            float[] float1 = new float[float0.length];
            arrayCopy(float1, float0, 0, float0.length);
            return float1;
        }
    }

    public static <E> E[] clone(E[] object0) {
        if (isNullOrEmpty(object0)) {
            return (E[])object0;
        } else {
            Object[] object1 = newInstance(object0.getClass().getComponentType(), object0.length);
            arrayCopy(object1, object0, 0, object0.length);
            return (E[])object1;
        }
    }

    public static <E> boolean isNullOrEmpty(E[] object) {
        return object == null || object.length == 0;
    }

    public static boolean isNullOrEmpty(int[] _int) {
        return _int == null || _int.length == 0;
    }

    public static boolean isNullOrEmpty(float[] _float) {
        return _float == null || _float.length == 0;
    }

    public static <E> boolean isNullOrEmpty(List<E> list) {
        return list == null || list.isEmpty();
    }

    public static <E> boolean isNullOrEmpty(Iterable<E> it) {
        if (it instanceof List) {
            return isNullOrEmpty((List<E>)it);
        } else {
            boolean _boolean = true;
            Iterator iterator = it.iterator();
            if (iterator.hasNext()) {
                Object object = iterator.next();
                _boolean = false;
            }

            return _boolean;
        }
    }

    public static <E> E getOrDefault(List<E> list, int _int) {
        return getOrDefault(list, _int, null);
    }

    public static <E> E getOrDefault(List<E> list, int _int, E object) {
        return (E)(_int >= 0 && _int < list.size() ? list.get(_int) : object);
    }

    public static <E> E getOrDefault(E[] object1, int _int, E object0) {
        return (E)(object1 != null && _int >= 0 && _int < object1.length ? object1[_int] : object0);
    }

    public static float getOrDefault(float[] float1, int _int, float float0) {
        return float1 != null && _int >= 0 && _int < float1.length ? float1[_int] : float0;
    }

    public static int[] arraySet(int[] int0, int int3) {
        if (isNullOrEmpty(int0)) {
            return int0;
        } else {
            int int1 = 0;

            for (int int2 = int0.length; int1 < int2; int1++) {
                int0[int1] = int3;
            }

            return int0;
        }
    }

    public static float[] arraySet(float[] float0, float float1) {
        if (isNullOrEmpty(float0)) {
            return float0;
        } else {
            int int0 = 0;

            for (int int1 = float0.length; int0 < int1; int0++) {
                float0[int0] = float1;
            }

            return float0;
        }
    }

    public static <E> E[] arraySet(E[] object0, E object1) {
        if (isNullOrEmpty(object0)) {
            return (E[])object0;
        } else {
            int int0 = 0;

            for (int int1 = object0.length; int0 < int1; int0++) {
                object0[int0] = object1;
            }

            return (E[])object0;
        }
    }

    public static <E> E[] arrayPopulate(E[] object, Supplier<E> supplier) {
        if (isNullOrEmpty(object)) {
            return (E[])object;
        } else {
            int int0 = 0;

            for (int int1 = object.length; int0 < int1; int0++) {
                object[int0] = supplier.get();
            }

            return (E[])object;
        }
    }

    public static void insertAt(int[] int1, int int2, int int3) {
        for (int int0 = int1.length - 1; int0 > int2; int0--) {
            int1[int0] = int1[int0 - 1];
        }

        int1[int2] = int3;
    }

    public static void insertAt(float[] float0, int int1, float float1) {
        for (int int0 = float0.length - 1; int0 > int1; int0--) {
            float0[int0] = float0[int0 - 1];
        }

        float0[int1] = float1;
    }

    public static <E> E[] toArray(List<E> list) {
        if (list != null && !list.isEmpty()) {
            Object[] object = newInstance(list.get(0).getClass(), list.size());
            arrayCopy(object, list);
            return (E[])object;
        } else {
            return null;
        }
    }

    public static <E> int indexOf(E[] object1, int int1, E object0) {
        for (int int0 = 0; int0 < int1; int0++) {
            if (object1[int0] == object0) {
                return int0;
            }
        }

        return -1;
    }

    public static int indexOf(float[] float1, int int1, float float0) {
        for (int int0 = 0; int0 < int1; int0++) {
            if (float1[int0] == float0) {
                return int0;
            }
        }

        return -1;
    }

    public static boolean contains(float[] float0, int _int, float float1) {
        return indexOf(float0, _int, float1) != -1;
    }

    public static int indexOf(int[] int3, int int1, int int2) {
        for (int int0 = 0; int0 < int1; int0++) {
            if (int3[int0] == int2) {
                return int0;
            }
        }

        return -1;
    }

    public static boolean contains(int[] int0, int int1, int int2) {
        return indexOf(int0, int1, int2) != -1;
    }

    public static <E> void forEach(List<E> list, Consumer<? super E> consumer) {
        try {
            if (list == null) {
                return;
            }

            int int0 = 0;

            for (int int1 = list.size(); int0 < int1; int0++) {
                Object object = list.get(int0);
                consumer.accept(object);
            }
        } finally {
            Pool.tryRelease(consumer);
        }
    }

    public static <E> void forEach(Iterable<E> it, Consumer<? super E> consumer) {
        if (it == null) {
            Pool.tryRelease(consumer);
        } else if (it instanceof List) {
            forEach((List<E>)it, consumer);
        } else {
            try {
                for (Object object : it) {
                    consumer.accept(object);
                }
            } finally {
                Pool.tryRelease(consumer);
            }
        }
    }

    public static <E> void forEach(E[] object, Consumer<? super E> consumer) {
        if (!isNullOrEmpty(object)) {
            int int0 = 0;

            for (int int1 = object.length; int0 < int1; int0++) {
                consumer.accept(object[int0]);
            }
        }
    }

    public static <K, V> V getOrCreate(HashMap<K, V> hashMap, K object1, Supplier<V> supplier) {
        Object object0 = hashMap.get(object1);
        if (object0 == null) {
            object0 = supplier.get();
            hashMap.put(object1, object0);
        }

        return (V)object0;
    }

    public static <E> void sort(Stack<E> stack, Comparator<E> comparator) {
        try {
            stack.sort(comparator);
        } finally {
            Pool.tryRelease(comparator);
        }
    }

    public static <E> boolean sequenceEqual(E[] object, List<? extends E> list) {
        return sequenceEqual(object, list, PZArrayUtil.Comparators::objectsEqual);
    }

    public static <E> boolean sequenceEqual(E[] object, List<? extends E> list, Comparator<E> comparator) {
        return object.length == list.size() && sequenceEqual(asList((E[])object), list, comparator);
    }

    public static <E> boolean sequenceEqual(List<? extends E> a, List<? extends E> b) {
        return sequenceEqual(a, b, PZArrayUtil.Comparators::objectsEqual);
    }

    public static <E> boolean sequenceEqual(List<? extends E> a, List<? extends E> b, Comparator<E> comparator) {
        if (a.size() != b.size()) {
            return false;
        } else {
            boolean _boolean = true;
            int int0 = 0;

            for (int int1 = a.size(); int0 < int1; int0++) {
                Object object0 = a.get(int0);
                Object object1 = b.get(int0);
                if (comparator.compare(object0, object1) != 0) {
                    _boolean = false;
                    break;
                }
            }

            return _boolean;
        }
    }

    public static int[] arrayAdd(int[] int1, int[] int2) {
        for (int int0 = 0; int0 < int1.length; int0++) {
            int1[int0] += int2[int0];
        }

        return int1;
    }

    public static class Comparators {
        public static <E> int referencesEqual(E object0, E object1) {
            return object0 == object1 ? 0 : 1;
        }

        public static <E> int objectsEqual(E object0, E object1) {
            return object0 != null && object0.equals(object1) ? 0 : 1;
        }

        public static int equalsIgnoreCase(String a, String b) {
            return StringUtils.equals(a, b) ? 0 : 1;
        }
    }

    public interface IListConverter1Param<S, E, T1> {
        E convert(S var1, T1 var2);
    }
}
